home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 3
/
Gold Medal Software - Volume 3 (Gold Medal) (1994).iso
/
music
/
melody21.arj
/
MELODY21.EXE
/
SOUNDER.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-07-26
|
5KB
|
143 lines
{
Background sound generation unit for Turbo Pascal programs
Originally written and released to Public Domain by:
Nels Anderson
92 Bishop Drive
Framingham, MA 01701
Adopted for use with Melody Master by Alexei A. Efros, Jr.
}
unit Sounder;
{
This UNIT can be used with MELODY MASTER's "TP back-gr" output
files to minimize the music development time. Please note,
however, that you may have some problems when playing high
notes. This happens when the note's frequency is greater than
255 (byte). To solve the problem try to lower your music: in
MELODY MASTER press F9 and then "8 down". Then, output it
again.
To use this unit, the main program needs to do the following:
uses Sounder, Crt;
Begin
GetIntVec($1C,Int1CSave); (save original interrupt vector)
SetIntVec($1C,New1CInt); (install timer interrupt)
.
. (body of program)
.
StartSound(@ArrayName,N,S);
(where: ArrayName is the name of the your melody,
N is the number if repeats,
S is the speed)
.
. (body of program)
.
SetIntVec($1C,Int1CSave); (restore original 1C interrupt)
NoSound;
end.
}
interface
Uses
Crt;
{$I FILENAME.PAS} { <---- Insert your music file name here! }
procedure StartSound(Notes: POINTER; Repeats: INTEGER; Speed: BYTE);
{ Sound Collection:
Each sound is an array of pairs of bytes, where the first byte of each
pair is the duration in 1/18th second units and the second byte of the
pair is the note frequency in 10's of Hertz. To use a sound, include
a command like the following in a program:
StartSound(@PhaserSound,3,1); {do phaser sound 3 times}
Type
ByteArray = array[1..2] of BYTE;
Var
SoundSpeed: BYTE; {multiplier used to slow down sounds}
SoundCount: BYTE; {counts how long current sound has been on}
MySound: ^ByteArray; {points to array of notes and durations}
New1CInt,{address of new interrupt}
Int1CSave: POINTER; {saves original $1C interrupt}
NumRepeats, {number of times to repeat sound}
MyClock, {general purpose timer}
SoundOff: INTEGER; {offset into note array}
SndFlg, {set when sounds allowed}
MakeSound: BOOLEAN; {set while sound is going}
implementation
procedure StartSound(Notes: POINTER; Repeats: INTEGER; Speed: BYTE);
{ Start generating the sound pointed to by Notes }
begin
SoundSpeed := Speed; {set speed}
SoundOff := 1; {offset into sound array}
SoundCount := 1; {counter for current note}
MySound := Notes; {pointer to sound array}
MakeSound := TRUE; {enable sounds}
NumRepeats := Repeats; {number times to repeat sound}
end; {StartSound procedure}
procedure TimerInt;
interrupt;
{ Clock tick interrupt
BIOS interrupt $1C has been replaced with the following routine. This
interrupt occurs on each clock tick (18 per second).
The interrupt mainly handles sounds. When the MakeSound flag is true,
the pointer MySound must be pointing to a byte array containing durations
and frequencies of sounds to be generated. Sounds will be generated from
the array until a duration of 0 is found.
A general purpose timer is also incremented each time the interrupt
occurs.
}
begin
Inc(MyClock); {increment timer}
if not SndFlg then begin {exit if sounds turned off}
MakeSound := FALSE;
Exit;
end;
if MakeSound then begin {if making a sound...}
Dec(SoundCount);
if SoundCount <= 0 then begin {if current sound done...}
NoSound;
SoundCount := SoundSpeed * MySound^[SoundOff];{get duration of next one}
if SoundCount > 0 then begin {if there is a next one...}
Inc(SoundOff);
Sound(10*MySound^[SoundOff]); {start it up}
Inc(SoundOff);
end
else begin {if end of sound array...}
Dec(NumRepeats); {decrement number of repeats}
if NumRepeats > 0 then begin {if we must repeat...}
SoundOff := 3; {reset offset into array}
SoundCount := MySound^[1]; {get duration of first note}
Sound(10*MySound^[2]); {start it up}
end
else begin {if all repeats now done...}
NoSound; {stop all sound}
MakeSound := FALSE; {reset flag}
end;
end;
end; {if SoundCount = 0}
end; {if making a sound}
end; {TimerInt interrupt procedure}
begin
SndFlg := TRUE; {sounds are allowed}
MakeSound := FALSE; {sound initially off}
MyClock := 0; {reset timer}
New1CInt := @TimerInt; {get address of interrupt}
end.